//四舍五入保留2位小数（若第二位小数为0，则保留一位小数）

import { _type } from "../utils/index.js";

// keepTwoDecimalk
export function _k(num, decimal = 2) {
    if (decimal == null) {
        return num
    }
    const g = Math.pow(10, decimal)
    return Math.round(num * g) / g;
}
// 二维数组 points [p1,p2]
// 点队列 vector
export const isQueue = (p) => Array.isArray(p) && p.every(t => Array.isArray(t))

// 点阵  [points1,points2]
// matrix ( a2-D array)
export const isMatrix = (p) => Array.isArray(p) && p.every(t => isQueue(t))


// 转弧度
export const _rad = (angle) => angle * Math.PI / 180
export const _deg = (r) => _k(r * 180 / Math.PI)
// 正玄
export const _sin = (angle, decimal) => _k(Math.sin(_rad(angle)), decimal)

// 余玄
export const _cos = (angle, decimal) => _k(Math.cos(_rad(angle)), decimal)


// 极坐标
export const _polar = (o = [0, 0], r = 0, a = 0) => {
    return [o[0] + r * _cos(a), o[1] + r * _sin(a)].map(t => _k(t))
}

export const _polarRad = (o = [0, 0], r = 0, a = 0) => {
    return [o[0] + r * Math.cos(a), o[1] + r * Math.sin(a)].map(t => _k(t))
}
// 中点 midpoint
export const _mid = (p1 = [0, 0], p2 = [0, 0]) => {
    if (isQueue(p1)) {
        let n = p1.length
        return p1.map((t, index) => {
            let next = p1[(index + 1) % n]
            return _mid(t, next)
        })
    }
    return [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2].map(t => _k(t))
}

// 距离
export const _dis = (p1 = [0, 0], p2 = [0, 0], decimal = 2) => {
    return _k(Math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1])), decimal)
}
// 夹角 toAngle
export const _angleRad = (p1 = [0, 0], p2 = [0, 0]) => {
    return Math.atan2(p2[1] - p1[1], p2[0] - p1[0])
}

export const _atan = (p1 = [0, 0], p2 = [0, 0]) => {
    return _deg(_angleRad(p1, p2))
}

// 三点夹角
export const _angleToRad = (A, O, B) => {
    let OA = _dis(O, A)
    let OB = _dis(O, B)
    let AB = _dis(A, B)
    let cosO = (OA * OA + OB * OB - AB * AB) / (2 * OA * OB)
    return Math.acos(cosO)
}

// 三点夹角
// angleTo
// cosO = (OA*OA + OB*OB - AB*AB ) / 2*OA*OB
export const includedAngle = (A, O, B) => {
    return _deg(_angleToRad(A, O, B))
}




// 中心点 _o
export const _o = points => {
    let n = points.length
    let sum = points.reduce((sum, t) => {
        sum[0] += t[0]
        sum[1] += t[1]
        return sum
    }, [0, 0])
    return sum.map(t => t / n)
}


// 放大缩小
export const _scale = (p, amplitude, o) => {
    if (isQueue(p)) {
        o = o || _o(p)
        return p.map(t => _scale(t, amplitude, o))
    }
    let deta = [p[0] - o[0], p[1] - o[1]]
    return [o[0] + deta[0] * amplitude, o[1] + deta[1] * amplitude]
}



// 线段平移
// 移动  相对距离
export const _move = (p, from, to, radio) => {
    let deta = [to[0] - from[0], to[1] - from[1]]
    if (isQueue(p)) {
        if (radio) {
            let points = p.map(t => [t[0] + deta[0], t[1] + deta[1]])
            return _scale(points, radio)
        }
        return p.map(t => [t[0] + deta[0], t[1] + deta[1]])
    } else {
        return [p[0] + deta[0], p[1] + deta[1]]
    }
}
// // 移动 绝对距离r
export const _moveDis = (p, o, r) => {
    let a = _angleRad(o, p)
    return _polarRad(p, r, a)
}

//  平移r   方向
// export const translate = (points, r = 100, direction = 0) => {
//     if (direction == null) {
//         return points.map(t => [t[0] + r, t[1]])
//     }
//     return points.map(t => [t[0] + r * _cos(direction), t[1] + r * _sin(direction)])
// }

export const translateX = (points = [], x = 100) => {
    if (isQueue(points)) {
        return points.map(t => translateX(t, x))
    }
    return [points[0] + x, points[1]]
}
export const translateY = (points = [], y = 100) => {
    if (isQueue(points)) {
        return points.map(t => translateY(t, y))
    }
    return [points[0], points[1] + y]
}

// 平移
export const translate = (points = [], options = {}) => {
    if (isQueue(points)) {
        return points.map(t => translate(t, options))
    }
    if (Array.isArray(options)) {
        let [x, y] = options
        return [points[0] + x, points[1] + y]
    }
    else if (_type(options) === 'object') {
        let { x, y } = options
        return [points[0] + x, points[1] + y]
    }
    return translateX(points, options)
}



// 旋转 围绕o点旋转a角度
export const rotate = (points, o, a) => {
    if (isQueue(points)) {
        return points.map(t => rotate(t, o, a))
    }
    let r = _dis(points, o)
    return _polar(o, r, a)
}


// 其中（rx0，ry0）是旋转中心，（x，y）待旋转点，（x0，y0）旋转后的新坐标。
export const _rotate = (p, o, a) => {
    if (a === 0) return p
    let [x, y] = p
    let [rx0, ry0] = o
    var x0 = (x - rx0) * _cos(a) - (y - ry0) * _sin(a) + rx0;
    var y0 = (x - rx0) * _sin(a) + (y - ry0) * _cos(a) + ry0;
    return [x0, y0].map(t => _k(t))
}

// 线段中点旋转
export const _rotate2 = (points, a) => {
    let o = _o(points)
    return points.map(t => {
        return _rotate(t, o, a)
    })
}


export const _lerp = (p1, p2, d) => {
    if (Array.isArray(p1)) {
        return p1.map((t, i) => _k(t + (p2[i] - t) * d));
    }
    return _k(p1 + (p2 - p1) * d)
}


// 垂直,转90度
export const vertical = (points, v = 1) => {
    if (isQueue(points)) {
        let len = points.length
        return points.map((t, index) => vertical(t, (index === 0 || index === len) ? 1 : -1))
    }

    return [points[1], v * points[0]]
}

// 数组降维
export const plainMatrix = (matrix, infinite = false) => {
    if (isQueue(matrix)) {
        let ps = []
        if (infinite) {
            // 降至1维
            matrix.forEach(t => {
                if (isQueue(t)) {
                    ps.push(...plainMatrix(t, infinite))
                } else {
                    ps.push(t)
                }
            });
        } else {
            // 降1维
            matrix.forEach(t => ps.push(...t))
        }
        return ps
    } else if (Array.isArray(matrix)) {
        return matrix
    }
}

// 坐标
export const coordinate = (matrix) => {
    let ps = []
    if (isQueue(matrix)) {
        matrix.forEach((t, y) => ps.push(t.map((t, x) => [x, y])));

    } else if (Array.isArray(matrix)) {
        ps = matrix.map((t, i) => i)
    }
    return ps
}
// 随机数
export const _random = (start = 0, end = 1) => {
    if (Array.isArray(start)) {
        let index = Math.floor(Math.random() * start.length)
        return start[index]
    }
    return Math.floor((Math.random() * (end - start)) + start);
}

// 转向量
export const _vec = (p1 = [], p2 = []) => {
    return p1.map((t, i) => p2[i] - t)
}

const _rotateVec = (v1, radians) => {
    var s = Math.sin(radians),
        c = Math.cos(radians);

    let [x, y] = v1
    return [x * c - y * s, y * c + x * s]
}
export const _verticalVec = (v = []) => {
    return _rotateVec(v, -90)
}

export const _addVec = (v = [], p = []) => {
    return v.map((t, i) => t + p[i])
}


// 知一边，求正方形四点
export const _squarePoints = (p1, p2, a = 0) => {
    let v = _vec(p1, p2)
    let vv = _rotateVec(v, -90 + a)
    return [p1, p2, _addVec(vv, p2), _addVec(vv, p1)]

}

// 点到线段的距离
export const _disToSeg = (p, [o, t]) => {
    // 夹角
    // let a = includedAngle(p, o, t)
    // return _dis(p, o) * _sin(a)

    let a = _angleToRad(p, o, t)
    return _dis(p, o) * Math.sin(a)
}

// 点到线段的垂足点
export const _footPoint = (p, [o, t]) => {
    // let a = includedAngle(p, o, t)
    // let r = _dis(p, o) * _cos(a)
    // return _polar(o, r, a + _atan(o, p))

    let a = _angleToRad(p, o, t)
    let r = _dis(p, o) * Math.cos(a)
    return _polarRad(o, r, a + _angleRad(o, p))
}